import 'dart:async';
import 'package:flutter/foundation.dart';

/// **CaretBlinker**
///
/// 用于控制文本编辑器插入符（光标）的闪烁效果。
/// 内部通过 `Timer.periodic` 周期性切换 [_isVisible]，并通过
/// [ChangeNotifier] 通知监听者（通常是 `setState` 或 `CustomPainter`）。
///
/// ### 功能
/// - [isVisible]：是否当前应该绘制光标；
/// - [start]：启动闪烁定时器；
/// - [stop]：停止闪烁定时器；
/// - [forceVisible]：强制点亮光标，并重置闪烁节奏；
///
/// ### 生命周期
/// - 需要在不再使用时调用 [dispose] 以释放定时器。
class CaretBlinker extends ChangeNotifier {
  /// 构造函数
  ///
  /// - [period]：光标闪烁的周期（默认 500ms，约等于标准编辑器节奏）。
  CaretBlinker({this.period = const Duration(milliseconds: 500)});

  /// 光标闪烁周期
  final Duration period;

  Timer? _timer;

  /// 内部可见性状态
  bool _isVisible = true;

  /// 外部可读属性：光标是否当前可见
  bool get isVisible => _isVisible;

  /// 启动光标闪烁定时器。
  ///
  /// - 每隔 [period] 翻转 [_isVisible] 并通知监听者；
  /// - 若已存在定时器，会先停止再启动（避免重复）。
  void start() {
    _timer?.cancel();
    _timer = Timer.periodic(period, (_) {
      _isVisible = !_isVisible;
      notifyListeners();
    });
  }

  /// 停止光标闪烁定时器。
  void stop() {
    _timer?.cancel();
    _timer = null;
  }

  /// 立刻点亮光标，并重置闪烁周期。
  ///
  /// - 将 [_isVisible] 设为 `true` 并通知监听者；
  /// - 若定时器存在，会调用 [start] 重启计时，确保不会
  ///   出现“刚点亮马上熄灭”的情况。
  void forceVisible() {
    _isVisible = true;
    notifyListeners();
    if (_timer == null) return;
    // 重启一轮定时器，避免立刻熄灭
    start();
  }

  @override
  void dispose() {
    stop();
    super.dispose();
  }
}
